﻿// -------------------------------------------------------------------------
//    @FileName         :    TestConsistentHash.h
//    @Author           :    gaoyi
//    @Date             :    2025/1/20
//    @Email            :    445267987@qq.com
//    @Module           :    TestConsistentHash
//
// -------------------------------------------------------------------------

/**
 * @file TestConsistentHash.h
 * @brief 一致性哈希算法单元测试
 * 
 * 此文件包含对NFConsistentHash和NFCommMapEx的全面单元测试，
 * 验证一致性哈希算法的正确性、性能和稳定性。
 * 
 * 测试覆盖范围：
 * - 基本功能测试：插入、删除、查找节点
 * - 一致性测试：节点变化时的数据分布一致性
 * - 性能测试：大量节点的处理性能
 * - 边界测试：空容器、单节点等特殊情况
 * - 负载均衡测试：数据分布的均匀性
 */

#pragma once

#include <gtest/gtest.h>
#include <chrono>
#include <random>
#include <set>
#include <unordered_map>
#include "NFComm/NFCore/NFConsistentHash.hpp"
#include "NFComm/NFCore/NFCommMapEx.hpp"

/**
 * @brief 一致性哈希算法基础功能测试类
 * 
 * 测试NFConsistentHash的基本功能，包括节点的增删查改、
 * 哈希环的构建和节点选择等核心功能。
 */
class NFConsistentHashTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 测试前的初始化工作
    }

    void TearDown() override
    {
        // 测试后的清理工作
    }
};

/**
 * @brief 测试一致性哈希的基本构造函数和初始化
 */
TEST_F(NFConsistentHashTest, Constructor)
{
    NFConsistentHash<std::string> hash;
    
    EXPECT_TRUE(hash.Empty());
    EXPECT_EQ(hash.Size(), 0);
}

/**
 * @brief 测试节点的插入和删除功能
 */
TEST_F(NFConsistentHashTest, InsertAndErase)
{
    NFConsistentHash<std::string> hash;
    
    // 测试插入节点
    hash.Insert("server1");
    EXPECT_FALSE(hash.Empty());
    EXPECT_GT(hash.Size(), 0);
    
    // 测试插入多个节点
    hash.Insert("server2");
    hash.Insert("server3");
    EXPECT_GT(hash.Size(), 0);
    
    // 测试删除节点
    hash.Erase("server2");
    EXPECT_GT(hash.Size(), 0);
    
    // 测试清空所有节点
    hash.ClearAll();
    EXPECT_TRUE(hash.Empty());
    EXPECT_EQ(hash.Size(), 0);
}

/**
 * @brief 测试节点选择的一致性
 */
TEST_F(NFConsistentHashTest, ConsistentNodeSelection)
{
    NFConsistentHash<std::string> hash;
    
    // 添加测试节点
    hash.Insert("server1");
    hash.Insert("server2");
    hash.Insert("server3");
    
    // 测试相同key总是选择相同的节点
    NFVirtualNode<std::string> node1, node2;
    EXPECT_TRUE(hash.GetSuitNode("user123", node1));
    EXPECT_TRUE(hash.GetSuitNode("user123", node2));
    EXPECT_EQ(node1.mxData, node2.mxData);
    
    // 测试不同key可能选择不同节点
    NFVirtualNode<std::string> node3;
    EXPECT_TRUE(hash.GetSuitNode("user456", node3));
    // 注意：不同key可能选择相同节点，这是正常的
}

/**
 * @brief 测试随机节点选择功能
 */
TEST_F(NFConsistentHashTest, RandomNodeSelection)
{
    NFConsistentHash<std::string> hash;
    
    // 添加测试节点
    hash.Insert("server1");
    hash.Insert("server2");
    hash.Insert("server3");
    
    // 测试随机选择
    NFVirtualNode<std::string> node;
    EXPECT_TRUE(hash.GetSuitNodeRandom(node));
    EXPECT_FALSE(node.mxData.empty());
    
    // 多次随机选择应该能选到不同节点（概率上）
    std::set<std::string> selectedNodes;
    for (int i = 0; i < 100; ++i)
    {
        if (hash.GetSuitNodeRandom(node))
        {
            selectedNodes.insert(node.mxData);
        }
    }
    // 应该能选到多个不同的节点
    EXPECT_GT(selectedNodes.size(), 1);
}

/**
 * @brief 测试一致性节点选择功能
 */
TEST_F(NFConsistentHashTest, ConsistentSelection)
{
    NFConsistentHash<std::string> hash;
    
    // 添加测试节点
    hash.Insert("server1");
    hash.Insert("server2");
    hash.Insert("server3");
    
    // 测试一致性选择
    NFVirtualNode<std::string> node1, node2;
    EXPECT_TRUE(hash.GetSuitNodeConsistent(node1));
    EXPECT_TRUE(hash.GetSuitNodeConsistent(node2));
    EXPECT_EQ(node1.mxData, node2.mxData);
}

/**
 * @brief 测试空哈希环的处理
 */
TEST_F(NFConsistentHashTest, EmptyHashRing)
{
    NFConsistentHash<std::string> hash;
    
    // 测试空哈希环的节点选择
    NFVirtualNode<std::string> node;
    EXPECT_FALSE(hash.GetSuitNode("user123", node));
    EXPECT_FALSE(hash.GetSuitNodeRandom(node));
    EXPECT_FALSE(hash.GetSuitNodeConsistent(node));
}

/**
 * @brief 测试单节点哈希环
 */
TEST_F(NFConsistentHashTest, SingleNode)
{
    NFConsistentHash<std::string> hash;
    
    // 添加单个节点
    hash.Insert("server1");
    
    // 所有key都应该选择同一个节点
    NFVirtualNode<std::string> node1, node2, node3;
    EXPECT_TRUE(hash.GetSuitNode("user123", node1));
    EXPECT_TRUE(hash.GetSuitNode("user456", node2));
    EXPECT_TRUE(hash.GetSuitNode("user789", node3));
    
    EXPECT_EQ(node1.mxData, "server1");
    EXPECT_EQ(node2.mxData, "server1");
    EXPECT_EQ(node3.mxData, "server1");
}

/**
 * @brief 测试节点变化时的数据迁移最小化
 */
TEST_F(NFConsistentHashTest, MinimalDataMigration)
{
    NFConsistentHash<std::string> hash;
    
    for (int i = 0; i < 10; ++i)
    {
        hash.Insert("server" + NFCommon::tostr(i));
    }

    // 记录初始分配
    std::unordered_map<std::string, std::string> initialMapping;
    std::vector<std::string> testKeys;
    for (int i = 0; i < 10000; i++)
    {
        testKeys.push_back("user" + NFCommon::tostr(i));
    }

    for (const auto& key : testKeys)
    {
        NFVirtualNode<std::string> node;
        if (hash.GetSuitNode(key, node))
        {
            initialMapping[key] = node.mxData;
        }
    }
    
    // 移除一个节点
    hash.Insert("server10");
    
    // 检查数据迁移情况
    int migrationCount = 0;
    for (const auto& key : testKeys)
    {
        NFVirtualNode<std::string> node;
        if (hash.GetSuitNode(key, node))
        {
            if (initialMapping[key] != node.mxData)
            {
                migrationCount++;
            }
        }
    }
    
    // 理论上，移除一个节点时，只有1/3的数据需要迁移
    // 但由于虚拟节点的存在，实际迁移可能更少
    EXPECT_LE(migrationCount, testKeys.size() / 10);
}

/**
 * @brief 测试负载均衡的均匀性
 */
TEST_F(NFConsistentHashTest, LoadBalancing)
{
    NFConsistentHash<std::string> md5hash(E_CONHASH_MD5HASH, 500);
    NFConsistentHash<std::string> ketamahash(E_CONHASH_KETAMAHASH, 500);
    NFConsistentHash<std::string> crc32hash(E_CONHASH_CRC32HASH, 500);

    for (int i = 0; i < 10; ++i)
    {
        md5hash.Insert("server" + NFCommon::tostr(i));
        ketamahash.Insert("server" + NFCommon::tostr(i));
        crc32hash.Insert("server" + NFCommon::tostr(i));
    }
    
    // 生成大量测试key
    std::vector<std::string> testKeys;
    for (int i = 0; i < 100000; ++i)
    {
        testKeys.push_back("user" + std::to_string(i));
    }
    
    // 统计每个节点的负载
    std::unordered_map<std::string, int> loadmd5Distribution;
    std::unordered_map<std::string, int> loadketamaDistribution;
    std::unordered_map<std::string, int> loadcrc32Distribution;
    for (const auto& key : testKeys)
    {
        NFVirtualNode<std::string> node;
        if (md5hash.GetSuitNode(key, node))
        {
            loadmd5Distribution[node.mxData]++;
        }
        if (ketamahash.GetSuitNode(key, node))
        {
            loadketamaDistribution[node.mxData]++;
        }
        if (crc32hash.GetSuitNode(key, node))
        {
            loadcrc32Distribution[node.mxData]++;
        }
    }
    
    int minLoad = INT_MAX;
    int maxLoad = 0;
    for (const auto& pair : loadmd5Distribution)
    {
        minLoad = std::min(minLoad, pair.second);
        maxLoad = std::max(maxLoad, pair.second);
    }
    
    // 负载差异不应该太大（理想情况下应该在20%以内）
    double loadRatio = (double)minLoad / maxLoad;
    EXPECT_GT(loadRatio, 0.6); // 允许40%的负载差异

    minLoad = INT_MAX;
    maxLoad = 0;
    for (const auto& pair : loadketamaDistribution)
    {
        minLoad = std::min(minLoad, pair.second);
        maxLoad = std::max(maxLoad, pair.second);
    }

    // 负载差异不应该太大（理想情况下应该在20%以内）
    loadRatio = (double)minLoad / maxLoad;
    EXPECT_GT(loadRatio, 0.6); // 允许40%的负载差异

    minLoad = INT_MAX;
    maxLoad = 0;
    for (const auto& pair : loadcrc32Distribution)
    {
        minLoad = std::min(minLoad, pair.second);
        maxLoad = std::max(maxLoad, pair.second);
    }

    // 负载差异不应该太大（理想情况下应该在20%以内）
    loadRatio = (double)minLoad / maxLoad;
    EXPECT_GT(loadRatio, 0.6); // 允许40%的负载差异
}

/**
 * @brief 测试大量节点的性能
 */
TEST_F(NFConsistentHashTest, PerformanceWithManyNodes)
{
    NFConsistentHash<std::string> hash;
    
    // 添加大量节点
    const int nodeCount = 100;
    for (int i = 0; i < nodeCount; ++i)
    {
        hash.Insert("server" + std::to_string(i));
    }
    
    EXPECT_EQ(hash.Size(), nodeCount * 500); // 每个节点500个虚拟节点
    
    // 性能测试：大量查找操作
    auto start = std::chrono::high_resolution_clock::now();
    
    const int lookupCount = 10000;
    for (int i = 0; i < lookupCount; ++i)
    {
        NFVirtualNode<std::string> node;
        hash.GetSuitNode("user" + std::to_string(i), node);
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    
    // 每次查找应该在微秒级别
    double avgTime = (double)duration.count() / lookupCount;
    EXPECT_LT(avgTime, 100); // 平均每次查找不超过100微秒
}

/**
 * @brief 测试不同类型的数据
 */
TEST_F(NFConsistentHashTest, DifferentDataTypes)
{
    // 测试字符串类型
    NFConsistentHash<std::string> strHash;
    strHash.Insert("server1");
    strHash.Insert("server2");
    
    NFVirtualNode<std::string> strNode;
    EXPECT_TRUE(strHash.GetSuitNode("user123", strNode));
    
    // 测试整数类型
    NFConsistentHash<int> intHash;
    intHash.Insert(1);
    intHash.Insert(2);
    
    NFVirtualNode<int> intNode;
    EXPECT_TRUE(intHash.GetSuitNode("user123", intNode));
    
    // 测试模板化的GetSuitNode方法
    NFVirtualNode<int> intNode2;
    EXPECT_TRUE(intHash.GetSuitNode(std::string("user456"), intNode2));
}

/**
 * @brief 测试虚拟节点的唯一性
 */
TEST_F(NFConsistentHashTest, VirtualNodeUniqueness)
{
    NFConsistentHash<std::string> hash;
    hash.Insert("server1");
    
    // 获取所有虚拟节点
    std::list<NFVirtualNode<std::string>> nodeList;
    EXPECT_TRUE(hash.GetNodeList(nodeList));
    
    // 检查虚拟节点的唯一性
    std::set<std::string> virtualNodeStrings;
    for (const auto& node : nodeList)
    {
        std::string nodeStr = node.ToStr();
        EXPECT_EQ(virtualNodeStrings.find(nodeStr), virtualNodeStrings.end());
        virtualNodeStrings.insert(nodeStr);
    }
    
    // 应该有500个唯一的虚拟节点
    EXPECT_EQ(virtualNodeStrings.size(), 500);
}

/**
 * @brief 扩展通信映射容器测试类
 * 
 * 测试NFCommMapEx的基本功能，包括智能指针管理、
 * 对象的增删查改等操作。
 */
class NFCommMapExTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 测试前的初始化工作
    }

    void TearDown() override
    {
        // 测试后的清理工作
    }
};

/**
 * @brief 测试扩展通信映射容器的基本功能
 */
TEST_F(NFCommMapExTest, BasicOperations)
{
    NFCommMapEx<std::string, int> container;
    
    // 测试初始状态
    EXPECT_EQ(container.Count(), 0);
    EXPECT_FALSE(container.ExistElement("key1"));
    
    // 测试添加元素
    auto element1 = NF_SHARE_PTR<int>(new int(100));
    EXPECT_TRUE(container.AddElement("key1", element1));
    EXPECT_EQ(container.Count(), 1);
    EXPECT_TRUE(container.ExistElement("key1"));
    
    // 测试重复添加
    auto element2 = NF_SHARE_PTR<int>(new int(200));
    EXPECT_FALSE(container.AddElement("key1", element2));
    
    // 测试获取元素
    auto retrieved = container.GetElement("key1");
    EXPECT_NE(retrieved, nullptr);
    EXPECT_EQ(*retrieved, 100);
    
    // 测试获取原始指针
    int* rawPtr = container.GetElementNude("key1");
    EXPECT_NE(rawPtr, nullptr);
    EXPECT_EQ(*rawPtr, 100);
    
    // 测试移除元素
    EXPECT_TRUE(container.RemoveElement("key1"));
    EXPECT_EQ(container.Count(), 0);
    EXPECT_FALSE(container.ExistElement("key1"));
    
    // 测试移除不存在的元素
    EXPECT_FALSE(container.RemoveElement("nonexistent"));
}

/**
 * @brief 测试扩展通信映射容器的遍历功能
 */
TEST_F(NFCommMapExTest, Iteration)
{
    NFCommMapEx<std::string, int> container;
    
    // 添加多个元素
    container.AddElement("key1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("key2", NF_SHARE_PTR<int>(new int(200)));
    container.AddElement("key3", NF_SHARE_PTR<int>(new int(300)));
    
    // 测试First和Next方法
    std::string key;
    auto element = container.First(key);
    EXPECT_NE(element, nullptr);
    
    // 收集所有元素
    std::set<int> values;
    std::set<std::string> keys;
    
    for (auto ptr = container.First(); ptr != nullptr; ptr = container.Next())
    {
        values.insert(*ptr);
    }
    
    for (auto ptr = container.First(key); ptr != nullptr; ptr = container.Next(key))
    {
        keys.insert(key);
    }
    
    EXPECT_EQ(values.size(), 3);
    EXPECT_EQ(keys.size(), 3);
    EXPECT_TRUE(values.find(100) != values.end());
    EXPECT_TRUE(values.find(200) != values.end());
    EXPECT_TRUE(values.find(300) != values.end());
}

/**
 * @brief 测试扩展通信映射容器的清空功能
 */
TEST_F(NFCommMapExTest, ClearAll)
{
    NFCommMapEx<std::string, int> container;
    
    // 添加元素
    container.AddElement("key1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("key2", NF_SHARE_PTR<int>(new int(200)));
    
    EXPECT_EQ(container.Count(), 2);
    
    // 清空容器
    EXPECT_TRUE(container.ClearAll());
    EXPECT_EQ(container.Count(), 0);
    EXPECT_FALSE(container.ExistElement("key1"));
    EXPECT_FALSE(container.ExistElement("key2"));
}

/**
 * @brief 测试空指针处理
 */
TEST_F(NFCommMapExTest, NullPointerHandling)
{
    NFCommMapEx<std::string, int> container;
    
    // 测试添加空指针
    EXPECT_FALSE(container.AddElement("key1", nullptr));
    EXPECT_EQ(container.Count(), 0);
    
    // 测试获取不存在的元素
    auto element = container.GetElement("nonexistent");
    EXPECT_EQ(element, nullptr);
    
    int* rawPtr = container.GetElementNude("nonexistent");
    EXPECT_EQ(rawPtr, nullptr);
}

/**
 * @brief 一致性扩展通信映射容器测试类
 * 
 * 测试NFConsistentCommMapEx的功能，包括一致性哈希
 * 与智能指针容器的结合使用。
 */
class NFConsistentCommMapExTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 测试前的初始化工作
    }

    void TearDown() override
    {
        // 测试后的清理工作
    }
};

/**
 * @brief 测试一致性扩展通信映射容器的基本功能
 */
TEST_F(NFConsistentCommMapExTest, BasicOperations)
{
    NFConsistentCommMapEx<std::string, int> container;
    
    // 添加元素
    container.AddElement("server1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("server2", NF_SHARE_PTR<int>(new int(200)));
    container.AddElement("server3", NF_SHARE_PTR<int>(new int(300)));
    
    EXPECT_EQ(container.Count(), 3);
    
    // 测试一致性选择
    auto element1 = container.GetElementBySuit("user123");
    EXPECT_NE(element1, nullptr);
    
    auto element2 = container.GetElementBySuit("user123");
    EXPECT_NE(element2, nullptr);
    EXPECT_EQ(*element1, *element2); // 相同key应该选择相同节点
    
    // 测试随机选择
    auto randomElement = container.GetElementBySuitRandom();
    EXPECT_NE(randomElement, nullptr);
    
    // 测试一致性选择（从0开始）
    auto consistentElement = container.GetElementBySuitConsistent();
    EXPECT_NE(consistentElement, nullptr);
}

/**
 * @brief 测试一致性扩展通信映射容器的节点变化
 */
TEST_F(NFConsistentCommMapExTest, NodeChanges)
{
    NFConsistentCommMapEx<std::string, int> container;
    
    // 初始状态
    container.AddElement("server1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("server2", NF_SHARE_PTR<int>(new int(200)));
    container.AddElement("server3", NF_SHARE_PTR<int>(new int(300)));
    
    // 记录初始分配
    std::unordered_map<std::string, int> initialMapping;
    std::vector<std::string> testKeys = {"user1", "user2", "user3", "user4", "user5"};
    
    for (const auto& key : testKeys)
    {
        auto element = container.GetElementBySuit(key);
        if (element)
        {
            initialMapping[key] = *element;
        }
    }
    
    // 移除一个节点
    container.RemoveElement("server2");
    
    // 检查数据迁移情况
    int migrationCount = 0;
    for (const auto& key : testKeys)
    {
        auto element = container.GetElementBySuit(key);
        if (element && initialMapping[key] != *element)
        {
            migrationCount++;
        }
    }
    
    // 移除节点后，部分数据会迁移到其他节点
    EXPECT_GT(migrationCount, 0);
    EXPECT_LT(migrationCount, testKeys.size()); // 不是所有数据都会迁移
}

/**
 * @brief 测试一致性扩展通信映射容器的负载均衡
 */
TEST_F(NFConsistentCommMapExTest, LoadBalancing)
{
    NFConsistentCommMapEx<std::string, int> container;
    
    // 添加节点
    container.AddElement("server1", NF_SHARE_PTR<int>(new int(1)));
    container.AddElement("server2", NF_SHARE_PTR<int>(new int(2)));
    container.AddElement("server3", NF_SHARE_PTR<int>(new int(3)));
    
    // 统计负载分布
    std::unordered_map<int, int> loadDistribution;
    const int testCount = 1000;
    
    for (int i = 0; i < testCount; ++i)
    {
        auto element = container.GetElementBySuit("user" + std::to_string(i));
        if (element)
        {
            loadDistribution[*element]++;
        }
    }
    
    // 检查负载分布的均匀性
    EXPECT_EQ(loadDistribution.size(), 3);
    
    int minLoad = INT_MAX;
    int maxLoad = 0;
    for (const auto& pair : loadDistribution)
    {
        minLoad = std::min(minLoad, pair.second);
        maxLoad = std::max(maxLoad, pair.second);
    }
    
    // 负载应该相对均匀
    double loadRatio = (double)minLoad / maxLoad;
    EXPECT_GT(loadRatio, 0.5); // 允许50%的负载差异
}

/**
 * @brief 测试一致性扩展通信映射容器的清空功能
 */
TEST_F(NFConsistentCommMapExTest, ClearAll)
{
    NFConsistentCommMapEx<std::string, int> container;
    
    // 添加元素
    container.AddElement("server1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("server2", NF_SHARE_PTR<int>(new int(200)));
    
    EXPECT_EQ(container.Count(), 2);
    
    // 清空容器
    EXPECT_TRUE(container.ClearAll());
    EXPECT_EQ(container.Count(), 0);
    
    // 清空后无法选择节点
    auto element = container.GetElementBySuit("user123");
    EXPECT_EQ(element, nullptr);
    
    auto randomElement = container.GetElementBySuitRandom();
    EXPECT_EQ(randomElement, nullptr);
    
    auto consistentElement = container.GetElementBySuitConsistent();
    EXPECT_EQ(consistentElement, nullptr);
}

/**
 * @brief 测试不同类型key的一致性选择
 */
TEST_F(NFConsistentCommMapExTest, DifferentKeyTypes)
{
    NFConsistentCommMapEx<std::string, int> container;
    
    container.AddElement("server1", NF_SHARE_PTR<int>(new int(100)));
    container.AddElement("server2", NF_SHARE_PTR<int>(new int(200)));
    
    // 测试字符串key
    auto element1 = container.GetElementBySuit(std::string("user123"));
    EXPECT_NE(element1, nullptr);
    
    // 测试整数key（使用模板方法）
    auto element2 = container.GetElementBySuit(123);
    EXPECT_NE(element2, nullptr);
    
    // 测试长整型key
    auto element3 = container.GetElementBySuit(123456789L);
    EXPECT_NE(element3, nullptr);
}

/**
 * @brief 综合测试：一致性哈希算法的完整工作流程
 */
TEST_F(NFConsistentCommMapExTest, CompleteWorkflow)
{
    NFConsistentCommMapEx<std::string, std::string> container;
    
    // 第一阶段：初始部署
    container.AddElement("server1", NF_SHARE_PTR<std::string>(new std::string("data1")));
    container.AddElement("server2", NF_SHARE_PTR<std::string>(new std::string("data2")));
    container.AddElement("server3", NF_SHARE_PTR<std::string>(new std::string("data3")));
    
    // 记录初始分配
    std::unordered_map<std::string, std::string> initialAllocation;
    std::vector<std::string> users = {"user1", "user2", "user3", "user4", "user5", "user6"};
    
    for (const auto& user : users)
    {
        auto element = container.GetElementBySuit(user);
        if (element)
        {
            initialAllocation[user] = *element;
        }
    }
    
    // 第二阶段：扩容
    container.AddElement("server4", NF_SHARE_PTR<std::string>(new std::string("data4")));
    
    // 检查扩容后的分配
    int migrationCount = 0;
    for (const auto& user : users)
    {
        auto element = container.GetElementBySuit(user);
        if (element && initialAllocation[user] != *element)
        {
            migrationCount++;
        }
    }
    
    // 扩容时数据迁移应该相对较少
    EXPECT_LT(migrationCount, users.size());
    
    // 第三阶段：缩容
    container.RemoveElement("server2");
    
    // 检查缩容后的分配
    int migrationCount2 = 0;
    for (const auto& user : users)
    {
        auto element = container.GetElementBySuit(user);
        if (element)
        {
            // 确保不会分配到已删除的服务器
            EXPECT_NE(*element, "data2");
        }
    }
    
    // 第四阶段：负载均衡验证
    std::unordered_map<std::string, int> finalLoad;
    for (int i = 0; i < 100; ++i)
    {
        auto element = container.GetElementBySuit("user" + std::to_string(i));
        if (element)
        {
            finalLoad[*element]++;
        }
    }
    
    // 验证负载分布
    EXPECT_EQ(finalLoad.size(), 3); // 应该只有3个服务器
    EXPECT_TRUE(finalLoad.find("data1") != finalLoad.end());
    EXPECT_TRUE(finalLoad.find("data3") != finalLoad.end());
    EXPECT_TRUE(finalLoad.find("data4") != finalLoad.end());
    EXPECT_TRUE(finalLoad.find("data2") == finalLoad.end()); // 已删除的服务器不应该有负载
} 